<template>
  <v-card>
    <v-toolbar color="cyan" dark height="45">
      <v-toolbar-title>消息队列状态</v-toolbar-title>
      <v-spacer></v-spacer>
    </v-toolbar>
    <v-card-text>
      <v-layout row wrap ref="mqWindow" v-resize="onResize">
        <v-flex xs12 sm6 md6>
          <svg id="mqSvg" :width="width" :height="height"></svg>
        </v-flex>
      </v-layout>
    </v-card-text>
  </v-card>
</template>

<script>
import * as d3 from 'd3'
export default {
  name: 'mq-svg',
  data () {
    return {
      layers: '',
      layers0: '',
      layers1: '',
      area: '',
      n: 5,
      m: 200,
      k: 20,
      width: 740,
      height: 270,
      initv: ''
    }
  },
  methods: {
    stackMax (layer) {
      return d3.max(layer, function (d) {
        return d[1]
      })
    },
    stackMin (layer) {
      return d3.min(layer, function (d) {
        return d[0]
      })
    },
    transition () {
      var t
      d3.selectAll('path')
        .data((t = this.layers1, this.layers1 = this.layers0, this.layers0 = t))
        .transition()
        .duration(2500)
        .attr('d', this.area)
    },
    bumps (n, m) {
      var a = []
      var i
      for (i = 0; i < n; ++i) a[i] = 0
      for (i = 0; i < m; ++i) this.bump(a, n)
      return a
    },
    bump (a, n) {
      let x = 1 / (0.1 + Math.random())
      let y = 2 * Math.random() - 0.5
      let z = 10 / (0.1 + Math.random())
      for (let i = 0; i < n; i++) {
        let w = (i / n - y) * z
        a[i] += x * Math.exp(-w * w)
      }
    },
    onResize () {
      this.width = this.$refs.mqWindow.clientWidth * 0.95
    }
  },
  mounted () {
    let stack = d3.stack().keys(d3.range(this.n)).offset(d3.stackOffsetWiggle)
    this.layers0 = stack(d3.transpose(d3.range(this.n).map(() => { return this.bumps(this.m, this.k) })))
    this.layers1 = stack(d3.transpose(d3.range(this.n).map(() => { return this.bumps(this.m, this.k) })))
    this.layers = this.layers0.concat(this.layers1)

    let svg = d3.select(document.getElementById('mqSvg'))
    let width = +svg.attr('width')
    let height = +svg.attr('height')

    let x = d3.scaleLinear()
      .domain([0, this.m - 1])
      .range([0, width])

    let y = d3.scaleLinear()
      .domain([d3.min(this.layers, this.stackMin), d3.max(this.layers, this.stackMax)])
      .range([height, 0])

    let z = d3.interpolateCool

    this.area = d3.area()
      .x(function (d, i) { return x(i) })
      .y0(function (d) { return y(d[0]) })
      .y1(function (d) { return y(d[1]) })

    svg.selectAll('path')
      .data(this.layers0)
      .enter().append('path')
      .attr('d', this.area)
      .attr('fill', function () { return z(Math.random()) })

    this.initv = setInterval(() => {
      this.transition()
    }, 3000)

    this.onResize()
  },
  destroyed () {
    clearInterval(this.initv)
  }
}
</script>

<style scoped>

</style>
